package com.rabbit.redis.annotation;

import java.lang.annotation.*;
import java.util.concurrent.TimeUnit;

/**
 * <h1>在需要使用缓存的Service方法上添加该注解</h1>
 *
 * 查询时使用缓存：
 *
 *  常规用法：
 *
 *      例1：@Cacheable(key = RedisKeyConstant.ALLOW_ACCESS, targetClass = AllowAccessDto.class)
 *          public List<AllowAccessDto> queryAllowAccessData() {
 *              return whiteListMapper.queryAllowAccessData();
 *          }
 *
 *  测试方法： com.rabbit.controller.EngineTestController下的prodCompany请求
 *
 *  特殊需求：（该用法要RedisKey后面记得加冒号 如：public static final String QUESTIONS = "analysis:questions:";
 *
 *      例2：@Cacheable(key = RedisKeyConstant.QUESTIONS, targetClass = QuestionRes.class, keySuffix = "#classify")
 *          public List<QuestionRes> queryQuestions(QuestionReq questionReq)
 *          会将questionReq中的classify字段的值，拼接在key后，此时真实的key= RedisKeyConstant.QUESTIONS+classify
 *
 * 更新mysql时删除缓存：
 *
 *      例1：@Cacheable(key = RedisKeyConstant.ALLOW_ACCESS, cacheType = Cacheable.CACHE_TYPE.UPDATE)
 *          public void update(WhiteUpdateReq whiteUpdateReq)
 *
 * @author zjw
 * @date 2021/6/28 9:28
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Cacheable {

    /**
     * Redis Key
     */
    String key();

    /**
     * 需要缓存的目标类型
     */
    Class<?> targetClass() default Object.class;

    /**
     * 过期策略
     */
    EXPIRE_TYPE expireType() default EXPIRE_TYPE.RANDOM;

    /**
     * 过期时间
     */
    int expire() default 0;

    /**
     * 时间单位
     */
    TimeUnit timeUnit() default TimeUnit.MINUTES;

    /**
     * 缓存操作类型
     */
    CACHE_TYPE cacheType() default CACHE_TYPE.QUERY;

    /**
     * Key的后缀(非必须）
     */
    String keySuffix() default "";

    /**
     * 缓存操作类型
     */
    enum CACHE_TYPE {
        /**
         * 查询和更新
         */
        QUERY,
        UPDATE
    }

    enum EXPIRE_TYPE {

        /**
         * 永不过期，随机，自定义
         */
        NEVER,
        RANDOM,
        CUSTOM
    }

}
